iT邦幫忙

2021 iThome 鐵人賽

DAY 25
1
自我挑戰組

新手全端工程師的職場成長歷程系列 第 25

Day25:【技術篇】JavaScript 套件 - classnames

  • 分享至 

  • xImage
  •  

一、前言

  classnames 是一個方便 JavaScript 管理 class name 的 package,可以有條件的設定 class name!
  因為工作後,學習到 Mithril.js 這個前端框架,雖然很冷門與小眾,但實際運用它後發現,其實它與 React.js 概念非常相似,所以本篇套件分享,也會介紹一點兩者實際使用的案例寫法~

二、說明與舉例

  如果我們要設定多個 class name 給一個元件,通常我們會這樣寫:

// React 實際使用案例
render() {
  return (<div className="class1 class2 class3">這是一個div</div>);
}

// Mithril 實際使用案例
return m('.class1.class2.class3', '這是一個div')

  可是如果要根據元件 state 或是 props 來改變這些 class狀態,就會顯得很複雜。為了避免這樣複雜的寫法,我們可以使用 classnames 來管理 class,當然,首先也是要先 install package:

$npm install classnames --save

  classnames 基本的用法,如下

import classNames from 'classnames';
classNames('foo', 'bar'); // => 'foo bar'

  classnames 是一個 function,可以傳入 string 或是 object,如果傳入 'foo' ,表示是 {foo: true} 的縮寫。當 key 的 value 是falsy (相當於false),表示是不顯示的 class,有時候配合判別式可以決定某個 state 或 props 情況下不顯示 class。

以下是官方說明的範例,看完應該就會秒懂:

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'

// 傳入多組string或object
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'

// 只要是falsy value,都會被忽略不顯示
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'

// 當傳入陣列時,每一個值都會扁平化
var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'

  而配合 ES6 的 Template literals,可以動態組合 key 的名稱:

let buttonType = 'primary';
classNames({ [`btn-${buttonType}`]: true });  // => 'btn-primary'

改寫上面提到複雜的寫法,就會是這樣:

// React 實際使用案例
import classNames from 'classnames';


render() {
  const classStr = classNames({
    'class1': true,
    'class2': this.props.isCompleted,
    'class3': !this.props.isCompleted
  });
  return (<div className={classStr}></div>);
}

// Mithril 實際使用案例
import classNames from 'classnames';

view(){
    return m('div.row.mb-n3', [
        m(Label, '類別'),
        m(Select, {
            class: classNames({
              'class1': this.valid.hasOwnProperty('type') && !this.model.hasError('type'),
              'class2': this.model.hasError('type')
            }),
        },
}

三、結論與自我鼓勵

  因為公司用的 Mithril.js 前端框架,網路資源非常少,所以也培養了我們團隊學習觀察別的框架,轉換思維寫成這個框架的運用技巧,雖然有時候會覺得研究的時間很長,但也很有成就感呢!


本文同步發佈於我的個人網站 Annie Code Life


上一篇
Day24:【技術篇】設定自己的GitHub Pages
下一篇
Day26:【技術篇】Webpack5 - Webpack之運作階段
系列文
新手全端工程師的職場成長歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
kk00915
iT邦新手 4 級 ‧ 2021-10-12 23:07:23

好 看不懂XDDD

我要留言

立即登入留言